
/***********************************************************************
 * Coord class
 * 
 * Implements two-dimensional coordinates
 *
 * Signature:
 *  public static Coord create (int x, int y);
 *  public static Coord origin ();
 *  public int xPos ();
 *  public int yPos ();
 *  public Coord move (int x, int y);
 *  public Coord add (Coord c);
 *  public boolean within (Coord c1, Coord c2);
 *  public double distance (Coord c);
 *  public int distanceInt (Coord c);
 *  public boolean equals (Coord c);
 *  public boolean equals (Object obj);
 *  public int hashCode ();
 *  public String toString ();
 ***********************************************************************/


public class Coord implements JSON_Saving<Coord> {

  private int xpos;
  private int ypos;

  private Coord (int x, int y) {
    xpos = x;
    ypos = y;
  }

  public static Coord create (int x, int y) {
    return new Coord(x,y);
  }

  public static Coord origin () {
    return create(0,0);
  }

  public int xPos () {
    return this.xpos;
  }

  public int yPos () {
    return this.ypos;
  }

  public Coord move (int x, int y) {
    return create(this.xPos()+x, this.yPos()+y);
  }

  public Coord add (Coord c) {
    return this.move (c.xPos(), c.yPos());
  }

  public boolean within (Coord c1, Coord c2) {
    return (c1.xPos() <= this.xPos() & 
	    c1.yPos() <= this.yPos() &
	    this.xPos() <= c2.xPos() &
	    this.yPos() <= c2.yPos());
  }

  public double distance (Coord c) {
    return Math.sqrt(Math.pow(this.xPos()-c.xPos(),2) + 
		     Math.pow(this.yPos()-c.yPos(),2));
  }

  public int distanceInt (Coord c) {
    Double v = new Double(Math.floor(this.distance(c)));
    return Math.round(v.floatValue());
  }

  public boolean equals (Coord c) {
    return (this.xPos()==c.xPos() && this.yPos()==c.yPos());
  }

    
  public boolean equals (Object obj) {
    return false;
  }

  public int hashCode () {
    return (this.xPos()+this.yPos())*(this.xPos()+this.yPos()+1)/2
      + this.yPos();
  }


  public String toString () {
    return "("+this.xPos()+","+this.yPos()+")";
  }

  
  public String jsonString() {
    return "[" + xpos + "," + ypos + "]";
  }

  public Coord fromJSONString(String jsonString) {
    String fields[] = JSON.decodeJSONArray(jsonString);
    if(fields.length != 2) {
      throw new RuntimeException(JSON.malformedErrorString("Coord",
							   jsonString));
    }

    try {
      return this.create(Integer.parseInt(fields[0]),
			 Integer.parseInt(fields[1]));
    } catch (NumberFormatException nfe) {
      throw new RuntimeException(JSON.malformedErrorString("Coord",
							   jsonString));
    }
  }
}
